package com.liuhongwei.test.builder;


import com.liuhongwei.test.bean.Constants;
import com.liuhongwei.test.bean.FieldInfo;
import com.liuhongwei.test.bean.TableInfo;
import com.liuhongwei.test.utils.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


public class BuildExtendMapper {

    private static final Logger log = LoggerFactory.getLogger(BuildExtendMapper.class);


//    public static void execute(TableInfo tableInfo) {
//        File folder = new File(Constants.PATH_MAPPERS);
//        if (!folder.exists()) {
//            folder.mkdirs();
//        }
//
//        OutputStream os = null;
//        OutputStreamWriter osw = null;
//        BufferedWriter bw = null;
//        try {
//            String beanName = tableInfo.getBeanName() + Constants.SUFFIX_MAPPER;
//
//            os = new FileOutputStream(folder + "/" + beanName + ".java");
//            osw = new OutputStreamWriter(os, "UTF-8");
//            bw = new BufferedWriter(osw);
//
//            bw.write("package " + Constants.PACKAGE_MAPPERS + ";\n\n");
//            //写入Import
//            writeImport(tableInfo, bw);
//            //写入类注释
//            BuildComment.createClassComment(bw, tableInfo.getComment() + Constants.SUFFIX_MAPPER);
//            //写入类声明
//            bw.write(String.format("public interface " + beanName + " extends BaseMapper<%s, %s> {\n\n", tableInfo.getBeanName(), tableInfo.getBeanParamName() ));
//
//            //写入属性
//            writeField(tableInfo, bw);
//
//            bw.write("}");
//            bw.flush();
//        } catch (Exception e) {
//            log.error("创建mapper失败", e);
//        } finally {
//            BuildBase.close(os, osw, bw);
//        }
//    }

    public static void execute(TableInfo tableInfo) {
        File folder = new File(Constants.PATH_MAPPERS);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        OutputStream os = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            String beanName = tableInfo.getBeanName() + Constants.SUFFIX_MAPPER_EXTEND;

            os = new FileOutputStream(folder + "/" + beanName + ".java");
            osw = new OutputStreamWriter(os, "UTF-8");
            bw = new BufferedWriter(osw);

            bw.write("package " + Constants.PACKAGE_MAPPERS + ";\n\n");
            //写入Import
            writeImport(tableInfo, bw);
            //写入类注释
            BuildComment.createClassComment(bw, tableInfo.getComment() + Constants.SUFFIX_MAPPER_EXTEND);
            //写入类声明
            bw.write(String.format("public interface " + beanName + " extends %s {\n\n", tableInfo.getBeanName() + Constants.SUFFIX_MAPPER ));

            //写入属性
            writeField(tableInfo, bw);

            bw.write("}");
            bw.flush();
        } catch (Exception e) {
            log.error("创建extend mapper失败", e);
        } finally {
            BuildBase.close(os, osw, bw);
        }
    }

    private static void writeField(TableInfo tableInfo, BufferedWriter bw) throws Exception {
        Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
        for (Entry<String, List<FieldInfo>> entry : keyIndexMap.entrySet()) {
            List<FieldInfo> fieldInfoList = entry.getValue();
            Integer index = 0;

            StringBuilder methodName = new StringBuilder();
            StringBuilder methodParam = new StringBuilder();

            for (FieldInfo fieldInfo : fieldInfoList) {
                index++;
                String propertyName = fieldInfo.getPropertyName();
                methodName.append(StringUtils.upperCaseFirst(propertyName));
                if (index < fieldInfoList.size()) {
                    methodName.append("And");
                }

                methodParam.append("@Param(\"" + propertyName + "\") " + fieldInfo.getJavaType() + " " + propertyName);
                if (index < fieldInfoList.size()) {
                    methodParam.append(", ");
                }
            }
            BuildComment.createFieldComment(bw, "根据" + methodName + "查询");
            bw.write(String.format("\t%s selectBy" + methodName + " (" + methodParam + ");\n\n", tableInfo.getBeanName()));

            BuildComment.createFieldComment(bw, "根据" + methodName + "更新");
            bw.write(String.format("\tInteger updateBy" + methodName + " (@Param(\"bean\") %s %s, " + methodParam + ");\n\n", tableInfo.getBeanName(), StringUtils.lowerCaseFirst(tableInfo.getBeanName())));

            BuildComment.createFieldComment(bw, "根据" + methodName + "删除");
            bw.write("\tInteger deleteBy" + methodName + " (" + methodParam + ");\n\n");
        }

        // 写入数量查询
        BuildComment.createFieldComment(bw, "查询数量");
        bw.write(String.format("\tInteger selectCount (@Param(\"query\") %s %s);\n\n", tableInfo.getBeanParamName(), tableInfo.getBeanParamName()));

        // 写入分页列表查询
        BuildComment.createFieldComment(bw, "分页列表查询");
        bw.write(String.format("\tList<%s> selectList (@Param(\"query\") %s %s);\n\n", tableInfo.getBeanName(), tableInfo.getBeanParamName(), tableInfo.getBeanParamName()));

        // 写入批量插入
        BuildComment.createFieldComment(bw, "批量插入");
        bw.write(String.format("\tInteger insertBatch (@Param(\"list\") List<%s> list);\n\n", tableInfo.getBeanName()));

        // 写入批量插入或更新
        BuildComment.createFieldComment(bw, "批量插入或更新");
        bw.write(String.format("\tInteger insertOrUpdateBatch (@Param(\"list\") List<%s> list);\n\n", tableInfo.getBeanName()));


    }

    private static void writeImport(TableInfo tableInfo, BufferedWriter bw) throws IOException {
        bw.write("import org.apache.ibatis.annotations.Param;\n");
        bw.write("import java.util.List;\n");
        bw.write("import " + Constants.PACKAGE_PO + "." + tableInfo.getBeanName() + ";\n");
        bw.write("import " + Constants.PACKAGE_MAPPERS + "." + tableInfo.getBeanName() + Constants.SUFFIX_MAPPER + ";\n");
        bw.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanName() + Constants.SUFFIX_BEAN_QUERY + ";\n");
    }

    public static void main(String[] args) {
        List<TableInfo> tables = BuildTable.getTable("tb_sys_country", "国家表");
        for (TableInfo tableInfo : tables) {
            BuildExtendMapper.execute(tableInfo);
        }
    }

}
